package com.lanmao.ems.dao.impl;

import com.lanmao.emc.dao.UpgradeDao;
import com.lanmao.emc.entity.FeIndexLogPO;
import com.lanmao.emc.entity.FeVersionPO;
import com.lanmao.emc.entity.VersionInfo;
import com.lanmao.emc.entity.VersionUsedInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

import static com.lanmao.emc.constant.FieldConstant.*;

/**
 * 描述：
 *
 * @author lanmao
 * @since 2024年11月11日 20:39
 */
@Repository
@Slf4j
public abstract class UpgradeDaoImpl implements UpgradeDao {
    @Autowired
    protected JdbcTemplate jdbcTemplate;

    @Override
    public FeVersionPO findLastVersion() {
        String sql = "select * from " + TABLE_VERSION + " order by id desc limit 1";
        try {
            return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(FeVersionPO.class));
        } catch (Exception e) {
            log.warn(e.getMessage());
        }
        return null;
    }

    @Override
    public boolean allTableExist(String... tables) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(getTableExistSql());
        List<Object> list = new ArrayList<>();
        for (String table : tables) {
            list.add(table);
            stringBuilder.append("?,");
        }
        stringBuilder.deleteCharAt(stringBuilder.length() - 1).append(")");
        Integer result = jdbcTemplate.queryForObject(stringBuilder.toString(), Integer.class, list.toArray());
        return result != null && result == tables.length;
    }

    abstract String getTableExistSql() ;


    @Override
    public List<VersionUsedInfo> findAllVersionByIndexName(String indexName) {
        String sql = "select " + INDEX_REL_NAME + "," + IS_USED +
                " from " + TABLE_INDEX_LOG +
                " where " + INDEX_NAME + " = '" + indexName + "' and " + SUCCESS + " = 't' order by " + CREATE_TIME + " desc ";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(VersionUsedInfo.class));

    }


    @Override
    public void batchSave(List<FeIndexLogPO> list) {
        String builder = "insert into " + TABLE_INDEX_LOG + " (" +
                INDEX_NAME + "," +
                INDEX_REL_NAME + "," +
                VERSION + "," +
                PROJECT_NAME + "," +
                IS_USED + "," +
                CREATE_TIME + "," +
                COST_TIME + "," +
                ERROR_INFO + "," +
                SUCCESS + "," +
                COUNT +
                ")" +
                " values (?,?,?,?,?,?,?,?,?,?)";
        List<Object[]> batchArgs = new ArrayList<>();
        for (FeIndexLogPO po : list) {
            Object[] arg = {po.getIndexName(), po.getIndexRelName(), po.getVersion(), po.getProjectName(), po.getIsUsed(),
                    po.getCreateTime(), po.getCostTime(), po.getErrorInfo() == null ? "" : po.getErrorInfo(), po.getSuccess(), po.getCount()};
            batchArgs.add(arg);
        }
        jdbcTemplate.batchUpdate(builder, batchArgs);
    }

    @Override
    public void batchupdate(List<String> list) {
        jdbcTemplate.batchUpdate(list.toArray(new String[0]));
    }

    @Override
    public void updateIsUsedByIndexAndVersion(String index, String version) {
        String sql = "update " + TABLE_INDEX_LOG +
                " set " + IS_USED + " = CASE WHEN " + VERSION + "='" + version + "' THEN 1 ELSE 0 END " +
                " WHERE " + INDEX_NAME + " = '" + index + "'";
        jdbcTemplate.update(sql);
    }

    @Override
    public void updateIsUsedByIndexName(List<String> indexList) {
        StringBuilder sb = new StringBuilder();
        List<Object> list = new ArrayList<>();
        sb.append("update " + TABLE_INDEX_LOG)
                .append(" set ").append(IS_USED).append(" = 0 ")
                .append(" where ").append(IS_USED).append(" =1 and ").append(INDEX_NAME).append(" in (");
        for (String index : indexList) {
            list.add(index);
            sb.append("?,");
        }
        sb.deleteCharAt(sb.length() - 1).append(")");
        jdbcTemplate.update(sb.toString(), list.toArray());
    }

    @Override
    public void deleteByIndexRelName(List<String> indexList) {
        List<Object> list = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        builder.append("delete from " + TABLE_INDEX_LOG + " where ").append(INDEX_REL_NAME).append(" in (");
        for (String index : indexList) {
            list.add(index);
            builder.append("?,");
        }
        builder.deleteCharAt(builder.length() - 1).append(")");
        jdbcTemplate.update(builder.toString(), list.toArray());
    }

    @Override
    public List<VersionInfo> findAllLastErrorIndex() {
        String sql1 = " ( select " + INDEX_NAME + "," + VERSION + "," + SUCCESS +
                ",ROW_NUMBER() OVER (PARTITION BY " + INDEX_NAME + " ORDER BY " + VERSION + " DESC , " + CREATE_TIME + " desc) "
                + " as rn from " + TABLE_INDEX_LOG + " ) a ";
        String sql = "select a." + INDEX_NAME + ",a." + VERSION + " from " + sql1 + " where a.rn=1 and a." + SUCCESS + "='f'";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(VersionInfo.class));

    }

    @Override
    public void saveVersion(FeVersionPO po) {
        List<Object> list = new ArrayList<>();
        list.add(po.getVersion());
        list.add(po.getDescription());
        list.add(po.getCreateTime());
        list.add(po.getId());
        list.add(po.getRemark());
        String sql = "insert into " + TABLE_VERSION + " (" + VERSION + "," + DESC + "," + CREATE_TIME + "," + ID + "," + REMARK + " ) VALUES (?,?,?,?,?)";
        jdbcTemplate.update(sql, list.toArray());
    }

    @Override
    public List<FeVersionPO> findAllVersion() {
        String sql = "select " + REMARK + " , " + VERSION + " from " + TABLE_VERSION;
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(FeVersionPO.class));
    }
}